package com.cfw.exception;

import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;

public class CustomHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {

	private int order = Ordered.LOWEST_PRECEDENCE;
	private String defaultErrorView;
	private Properties exceptionMappings;
	
	private static final Logger logger = LoggerFactory.getLogger(CustomHandlerExceptionResolver.class);
	
    public void setDefaultErrorView(String defaultview) {
    	this.defaultErrorView = defaultview;
    }
    
    public void setexceptionMappings(Properties props) {
    	this.exceptionMappings = props;
    }
	
	public void setOrder(final int order) {
		this.order = order;
	}
	
	public int getOrder() {
		return this.order;
	}
	    
		private boolean isAjax(HttpServletRequest request) {
	        return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
	    }
	
	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object object, Exception exception) {
		logger.debug("*** start method resolveException ***");
		
		ModelAndView mnv =	null;

		// ModelAndView의 생성
		if (isAjax(request)) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            
            mnv = new ModelAndView(new MappingJacksonJsonView());
		} else {
			final String exName = exception.getClass().getName();
			String viewName = this.defaultErrorView;
			
			if (this.exceptionMappings != null) {
				viewName = this.exceptionMappings.getProperty(exName);
			}
			logger.debug("***** " + viewName + " *****");
			
			mnv =	new ModelAndView(viewName);
		}

		// TODO: BizException인 경우와 그 외 Exception일 경우, 각각 Exception Code, Message를 전달해주는 부분 구현
		mnv.addObject("error.code", "001");
		mnv.addObject("error.message", "오류 발생");
		
		return mnv;
	}
}
